package com.karry.yl.web.financial;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.karry.commons.Constants;
import com.karry.commons.base.SuperController;
import com.karry.commons.vo.JsonResponse;
import com.karry.commons.vo.LayTableResponse;
import com.karry.yl.domain.baseinfo.Organization;
import com.karry.yl.domain.baseinfo.PaymentInfo;
import com.karry.yl.domain.elder.Elderly;
import com.karry.yl.domain.financial.Receipt;
import com.karry.yl.domain.financial.ReceiptItems;
import com.karry.yl.domain.services.Records;
import com.karry.yl.service.baseinfo.OrganizationService;
import com.karry.yl.service.baseinfo.PaymentInfoService;
import com.karry.yl.service.elder.ElderlyService;
import com.karry.yl.service.financial.ReceiptItemsService;
import com.karry.yl.service.financial.ReceiptService;
import com.karry.yl.service.services.RecordsService;
import org.ponly.payment.util.SignUtils;
import org.ponly.payment.util.XmlUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 收款单Controller
 */

@Controller
@RequestMapping("/receipt")
public class ReceiptController extends SuperController {

    private static final Logger log = LoggerFactory.getLogger(ReceiptController.class);
    @Autowired
    private ReceiptService receiptService;
    @Autowired
    private ReceiptItemsService receiptItemsService;
    @Autowired
    private RecordsService recordsService;
    @Autowired
    private ElderlyService elderlyService;
    @Autowired
    private PaymentInfoService paymentInfoService;
    @Autowired
    private OrganizationService organizationService;

    @RequestMapping
    public String listUI(){
        return "financial/receipt/list";
    }

    @RequestMapping("/add")
    public String addUI(){
        return "financial/receipt/add";
    }

    @RequestMapping("edit")
    public String editUI(Long id, ModelMap map){
        Receipt receipt = receiptService.selectOne(new EntityWrapper<Receipt>().eq("id",id).eq("orgId",currentUser.getOrgId()).eq("deleted",false));
        List<ReceiptItems> items = receiptItemsService.selectList(new EntityWrapper<ReceiptItems>().eq("receiptId", id).eq("deleted",false));
        /*List<Long> recordsIds = new ArrayList<>();
        for(ReceiptItems ri : items){
            if (ri.getType() == ReceiptItems.TYPE_FW){
                recordsIds.add(ri.getRecordsId());
            }
        }
        if(recordsIds.size() > 0){
            List<Records> recordsList = recordsService.selectBatchIds(recordsIds); //收费单已经纳入的的服务项目
            map.put("recordsList",recordsList);
        }
        //收费单未纳入的服务项目
        List<Records> recordsList1 = recordsService.selectList(new EntityWrapper<Records>().eq("orgId", currentUser.getOrgId()).eq("elderlyId", receipt.getElderlyId()).eq("status",Records.STATUS_0).eq("deleted",false));
        map.put("recordsList1",recordsList1);*/
        map.put("items",items);
        map.put("receipt",receipt);
        String rtUrl="";
        switch (receipt.getType()){
            case 1: rtUrl = "financial/receipt/edit_fw";break;
            case 2: rtUrl = "financial/receipt/edit_tc";break;
            case 3: rtUrl = "financial/receipt/edit_other";break;
            case 4: rtUrl = "";break;
        }
        return rtUrl;
    }

    /**
     * 查看详情
     * @param id
     * @return
     */
    @RequestMapping("/detail")
    public String detail(Long id,ModelMap map){
        Receipt receipt = receiptService.selectOne(new EntityWrapper<Receipt>().eq("id",id).eq("orgId",currentUser.getOrgId()).eq("deleted",false));
        List<ReceiptItems> items = receiptItemsService.selectList(new EntityWrapper<ReceiptItems>().eq("receiptId", id).eq("deleted",false));
        map.put("receipt",receipt);
        map.put("items",items);
        return "financial/receipt/detail";
    }

    @RequestMapping("/list")
    @ResponseBody
    public LayTableResponse listUI(int page, int limit,Integer type,Integer status,String elderlyName){
        Wrapper<Receipt> receiptWrapper = new EntityWrapper<Receipt>().eq("orgId", currentUser.getOrgId()).eq("deleted",false);
        if(null != type){
            receiptWrapper.eq("type",type);
        }
        if(null != status){
            receiptWrapper.eq("status",status);
        }
        if(!StringUtils.isEmpty(elderlyName)){
            receiptWrapper.like("elderlyName",elderlyName);
        }
        Page<Receipt> receiptPage = receiptService.selectPage(new Page<Receipt>(page, limit),receiptWrapper.orderBy("createdTime",false));
        return new LayTableResponse(receiptPage.getRecords(),receiptPage.getTotal());
    }

    @RequestMapping("/save")
    public String save(Receipt receipt, /*@RequestParam(name="recordsId",required = false) List<Long> recordsIds,*/ @RequestParam(name="itemsName",required = false) String[] itemsNames, @RequestParam(name="monery",required = false)BigDecimal[] monery){
        List<ReceiptItems> items = new ArrayList<>();
        if(null != itemsNames) {
            for(int i = 0; i < itemsNames.length; i++){
                ReceiptItems receiptItems = new ReceiptItems(itemsNames[i], monery[i], ReceiptItems.TYPE_QT);
                items.add(receiptItems);
            }
        }
        /*if(null != recordsIds){
            List<Records> recordsList = recordsService.selectBatchIds(recordsIds);
            for(Records records : recordsList){
                ReceiptItems receiptItems = new ReceiptItems(records.getItemName(),records.getCost(),ReceiptItems.TYPE_FW);
                receiptItems.setRecordsId(records.getId());
                items.add(receiptItems);
            }
        }*/
        receipt.setOrgId(currentUser.getOrgId());
        receipt.setOrgName(currOrganization.getName());
        receipt.setStatus(Receipt.STATUS_ZC);
        receipt.setUserId(currentUser.getId());
        receiptService.save(receipt,items);  //保存及收费项目
        return "redirect:/receipt";
    }

    @RequestMapping("/update")
    public String update(Receipt receipt, /*@RequestParam(name="recordsId",required = false) List<Long> recordsIds,*/ @RequestParam(name="itemsName",required = false) String[] itemsNames, @RequestParam(name="monery",required = false)BigDecimal[] monery,HttpSession session){
        List<ReceiptItems> items = new ArrayList<>();
        if(receipt.getType() == 3){
            if(null != itemsNames) {
                for(int i = 0; i < itemsNames.length; i++){
                    ReceiptItems receiptItems = new ReceiptItems(itemsNames[i], monery[i], ReceiptItems.TYPE_QT);
                    items.add(receiptItems);
                }
            }
        }
        receiptService.update(receipt,items);  //保存及收费项目
        return "redirect:/receipt";
    }

    /**
     * 删除
     * @param
     * @return
     */
    @RequestMapping(path = "/delete")
    public String delete(@RequestParam("id") List<Long> ids){
        receiptService.delete(ids);
        return "redirect:/receipt";
    }

    /**
     * 选择老人页面
     * @return
     */
    @RequestMapping("/select/elderly")
    public String selectElderlyUI(){
        return "financial/receipt/selectElderly";
    }


    /**
     * 选择老人的老人数据
     * @param page
     * @param limit
     * @param healthCondition
     * @param checkedIn
     * @param code
     * @param name
     * @return
     */
    @RequestMapping("/select/elderly/list")
    @ResponseBody
    public LayTableResponse selectElderlyList(int page, int limit,Integer healthCondition,Integer checkedIn,String code,String name){
        Wrapper<Elderly> elderlyWrapper = new EntityWrapper<Elderly>().eq("orgId", currentUser.getOrgId()).eq("deleted",false);
        if(!StringUtils.isEmpty(healthCondition)){
            elderlyWrapper.eq("healthCondition",healthCondition);
        }
        if(!StringUtils.isEmpty(checkedIn)){
            elderlyWrapper.eq("checkedIn",checkedIn);
        }
        if(!StringUtils.isEmpty(code)){
            elderlyWrapper.like("code",code);
        }
        if(!StringUtils.isEmpty(name)){
            elderlyWrapper.like("name",name);
        }
        Page<Elderly> elderlyPage = elderlyService.selectPage(new Page<Elderly>(page, limit),elderlyWrapper);
        return new LayTableResponse(elderlyPage.getRecords(),elderlyPage.getTotal());
    }

    /**
     * 获取某个老人未收费的服务记录
     * @param elderlyId 老人ID
     * @return
     */
    @RequestMapping("/elderly/records")
    @ResponseBody
   public JsonResponse records(Long elderlyId) {
        List<Records> recordsList = recordsService.selectList(new EntityWrapper<Records>().eq("orgId", currentUser.getOrgId()).eq("elderlyId", elderlyId).eq("status",Records.STATUS_0).eq("deleted",false));
        return JsonResponse.success(recordsList);
    }

    /**
     * 跳转到支付页面
     * @param id
     * @param type 1：在线支付 2：刷卡支付 3：现金支付
     * @param map
     * @return
     */
    @RequestMapping("/payment")
    public String paymentUI(Long id,int type,ModelMap map){
        Receipt receipt = receiptService.selectById(id);
        map.put("receipt",receipt);
        String path = "";
        switch (type){
            case 1: path = "financial/receipt/online_payment";break;
            case 2: path = "financial/receipt/cash_payment";break;
            case 3: path = "financial/receipt/cash_payment";break;

        }
        return path;
    }

    /**
     * 现金支付
     * @param code
     * @param monery
     * @return
     */
    @RequestMapping("/paycash")
    public String payByCash(String code,BigDecimal monery){
        receiptService.updateStatusForPayment(code,monery,Receipt.PM_XJ);
        return "redirect:/receipt";
    }

    /**
     * 在线支付(微信/支付宝/银联扫码支付)
     * @param receiptId
     * @param request
     * @return
     * @throws IOException
     */
    @RequestMapping("/payonline")
    public ModelAndView pay(Long receiptId, int channel, HttpServletRequest request, HttpSession session) {
        Receipt receipt = receiptService.selectById(receiptId);
        Map<String,String> paramsMap = new HashMap<>();
        String payMethod = null;
        if(channel == 1){  //微信支付
            paramsMap.put("service", "pay.weixin.native");
            payMethod = "微信";
        }else if(channel == 2){  //支付宝支付
            paramsMap.put("service", "pay.alipay.native");
            payMethod = "支付宝";
        }else if(channel == 3){  //银联支付
            paramsMap.put("service", "pay.unionpay.native");
            payMethod = "云闪付";
        }
        paramsMap.put("mch_id", ((PaymentInfo)session.getAttribute(Constants.SK_PAY_INFO)).getMchId());  //商户ID
        paramsMap.put("out_trade_no",receipt.getCode());
        paramsMap.put("total_fee",receipt.getAmount().multiply(new BigDecimal("100")).setScale(0, RoundingMode.HALF_UP).toString());  //将金额转换为分
        paramsMap.put("body",receipt.getName());
        paramsMap.put("key",((PaymentInfo)session.getAttribute(Constants.SK_PAY_INFO)).getKey());  //key
        paramsMap.put("attach",((PaymentInfo)session.getAttribute(Constants.SK_PAY_INFO)).getId().toString());  //key
        Map<String, String> rs = receiptService.pay(paramsMap);
        if(null != rs && ("0".equals(rs.get("status")) && "0".equals(rs.get("result_code")))){
            request.setAttribute("receiptName",receipt.getName());
            request.setAttribute("elderlyName",receipt.getElderlyName());
            request.setAttribute("receiptCode",rs.get("out_trade_no"));
            request.setAttribute("payMethod",payMethod);
            return new ModelAndView("financial/receipt/qrcode","rsMap",rs);  //跳转到二维码支付页面
        }else {
            return new ModelAndView("financial/receipt/fail","rsMap",rs);
        }


    }


    /**
     * 在线支付(微信/支付宝/银联扫码支付)
     * @param receiptId
     * @param request
     * @return
     * @throws IOException
     */
    @RequestMapping("/payonline2")
    public ModelAndView pay2(Long receiptId, int channel, HttpServletRequest request, Long orgId) {
        Receipt receipt = receiptService.selectById(receiptId);
        PaymentInfo paymentInfo = paymentInfoService.selectOne(new EntityWrapper<PaymentInfo>().eq("orgId", orgId));
        Map<String,String> paramsMap = new HashMap<>();
        String payMethod = null;
        if(channel == 1){  //微信支付
            paramsMap.put("service", "pay.weixin.native");
            payMethod = "微信";
        }else if(channel == 2){  //支付宝支付
            paramsMap.put("service", "pay.alipay.native");
            payMethod = "支付宝";
        }
        paramsMap.put("mch_id", paymentInfo.getMchId());  //商户ID
        paramsMap.put("out_trade_no",receipt.getCode());
        paramsMap.put("total_fee",receipt.getAmount().multiply(new BigDecimal("100")).setScale(0, RoundingMode.HALF_UP).toString());  //将金额转换为分
        paramsMap.put("body",receipt.getName());
        paramsMap.put("key",paymentInfo.getKey());  //key
        paramsMap.put("attach",paymentInfo.getId().toString());  //key
        Map<String, String> rs = receiptService.pay(paramsMap);
        if(null != rs && ("0".equals(rs.get("status")) && "0".equals(rs.get("result_code")))){
            request.setAttribute("receiptName",receipt.getName());
            request.setAttribute("elderlyName",receipt.getElderlyName());
            request.setAttribute("receiptCode",rs.get("out_trade_no"));
            request.setAttribute("payMethod",payMethod);
            return new ModelAndView("financial/receipt/out_pay_qrcode","rsMap",rs);  //跳转到二维码支付页面
        }else {
            return new ModelAndView("financial/receipt/fail","rsMap",rs);
        }


    }
    /**
     * 客户端轮询,判定是否支付成功
     * @param code
     * @return
     */
    @RequestMapping("/isPaid")
    @ResponseBody
    public JsonResponse isPaid(String code){
        boolean paid = receiptService.isPaid(code);
        return JsonResponse.success(paid);
    }

    /**
     * 账单支付异步通知
     * @param req
     * @param resp
     */
    @RequestMapping("/pay/notify")
    public void payNotify(HttpServletRequest req, HttpServletResponse resp){
        try {
            log.debug("收到通知...");
            req.setCharacterEncoding("utf-8");
            resp.setCharacterEncoding("utf-8");
            resp.setHeader("Content-type", "text/html;charset=UTF-8");
            String resString = XmlUtils.parseRequst(req);
            log.debug("请求的内容：" + resString);

            String respString = "error";
            if(resString != null && !"".equals(resString)){
                Map<String,String> map = XmlUtils.toMap(resString.getBytes(), "utf-8");
                String res = XmlUtils.toXml(map);
                log.debug("请求结果：" + res);
                if(map.containsKey("sign")){
                    String paymentInfoId = map.get("attach");
                    PaymentInfo paymentInfo = paymentInfoService.selectById(Long.valueOf(paymentInfoId));
                    if(!SignUtils.checkParam(map, paymentInfo.getKey())){
                        respString = "error";
                    }else{
                        String status = map.get("status");
                        if(status != null && "0".equals(status)){
                            String result_code = map.get("result_code");
                            if(result_code != null && "0".equals(result_code)){
                                //支付成功，将订单状态修改为 已支付
                                String total_fee = map.get("total_fee");  //支付金额
                                String out_trade_no = map.get("out_trade_no");  //账单号
                                receiptService.updateStatusForPayment(out_trade_no,new BigDecimal(total_fee).divide(new BigDecimal(100).setScale(2, RoundingMode.HALF_UP)),Receipt.PM_ZX);
                                respString = "success";
                            }
                        }
                    }
                }
            }
            resp.getWriter().write(respString);
        } catch (Exception e) {
            log.error("操作失败，原因：",e);
        }
    }


    /**
     *
     * @param receiptId
     * @return
     */
    @RequestMapping("/receipt_pay")
    public String sendReceipt(Long receiptId,ModelMap map){
        Receipt receipt = receiptService.selectById(receiptId);
        List<ReceiptItems> items = receiptItemsService.selectList(new EntityWrapper<ReceiptItems>().eq("receiptId", receiptId).eq("deleted",false));
        Organization org = organizationService.selectById(receipt.getOrgId());
        map.put("receipt",receipt);
        map.put("items",items);
        map.put("org",org);
        return "financial/receipt/receipt_pay";
    }


    /**
     * 微信wap支付
     * @param receiptId
     * @return
     * @throws IOException
     */
    @RequestMapping("/wappay")
    @ResponseBody
    public JsonResponse wapPay(Long receiptId, int channel) {
        JsonResponse rt;
        Receipt receipt = receiptService.selectById(receiptId);
        PaymentInfo paymentInfo = paymentInfoService.selectOne(new EntityWrapper<PaymentInfo>().eq("orgId", receipt.getOrgId()));
        Map<String,String> paramsMap = new HashMap<>();
        String payMethod = null;
        if(channel == 1){  //微信支付
            paramsMap.put("service", "pay.weixin.wappay");
            payMethod = "微信";
        }/*else if(channel == 2){  //支付宝支付
            paramsMap.put("service", "pay.alipay.jspay");
            payMethod = "支付宝";
        }*/else if(channel == 3){  //银联支付
            paramsMap.put("service", "pay.unionpay.wappay");
            payMethod = "银联";
        }
        paramsMap.put("mch_id", paymentInfo.getMchId());  //商户ID
        paramsMap.put("out_trade_no",receipt.getCode());
        paramsMap.put("total_fee",receipt.getAmount().multiply(new BigDecimal("100")).setScale(0, RoundingMode.HALF_UP).toString());  //将金额转换为分
        paramsMap.put("body",receipt.getName());
        paramsMap.put("key",paymentInfo.getKey());  //key
        paramsMap.put("attach",paymentInfo.getId().toString());  //key
        paramsMap.put("callback_url","https://www.kerry365.com/settlement/pay/callback");
        paramsMap.put("device_info","AND_WAP");
        paramsMap.put("mch_app_name","陕西养老服务信息平台");
        paramsMap.put("mch_app_id","https://www.kerry365.com");
        Map<String, String> rs = receiptService.pay(paramsMap);
        if(null != rs && ("0".equals(rs.get("status")) && "0".equals(rs.get("result_code")))){
            rs.put("receiptName",receipt.getName());
            rs.put("elderlyName",receipt.getElderlyName());
            rs.put("receiptCode",rs.get("out_trade_no"));
            rs.put("payMethod",payMethod);
            rt = JsonResponse.success(rs);
        }else {
            rt = JsonResponse.fail("操作失败",rs);
        }
        return rt;
    }
}
